using System;
using System.ComponentModel;
using System.ComponentModel.Design;

namespace VisualPureBasicIDE.FormDesigner.Implementations
{
    /// <summary>
    /// Summary description for SiteImpl.
    /// </summary>
    public class Site : ISite, IDictionaryService
    {
        private readonly IComponent _component;
        private readonly DictionaryService _dictionaryService;
        private readonly DesignerHost _host;
        private string _name;

        public Site(IComponent comp, string name, DesignerHost host)
        {
            if (comp == null)
            {
                throw new ArgumentException("comp");
            }
            if (host == null)
            {
                throw new ArgumentException("_host");
            }
            if (name == null || name.Trim().Length == 0)
            {
                throw new ArgumentException("name");
            }
            _component = comp;
            _host = host;
            _name = name;
            // create a dictionary service for this site
            _dictionaryService = new DictionaryService();
        }

        #region ISite Members

        public IComponent Component
        {
            get { return _component; }
        }

        public IContainer Container
        {
            get { return _host.Container; }
        }

        public bool DesignMode
        {
            get { return true; }
        }

        public string Name
        {
            get { return _name; }
            set
            {
                // null name is not valid
                if (value == null)
                {
                    throw new ArgumentException("value");
                }
                // if we have the same name
                if (string.Compare(value, _name, false) != 0)
                {
                    // make sure we have a valid name
                    var nameCreationService = (INameCreationService) _host.GetService(typeof (INameCreationService));
                    if (nameCreationService == null)
                    {
                        throw new Exception("Failed to service: INameCreationService");
                    }
                    if (nameCreationService.IsValidName(value))
                    {
                        var hostImpl = _host;
                        // get the current name
                        var oldName = _name;
                        // set the new name
                        MemberDescriptor md = TypeDescriptor.CreateProperty(_component.GetType(), "Name",
                                                                            typeof (string),
                                                                            new Attribute[] {});
                        // fire changing event
                        hostImpl.OnComponentChanging(_component, md);
                        // set the value
                        _name = value;
                        // we also have to fire the rename event
                        _host.OnComponentRename(_component, oldName, _name);
                        // fire changed event
                        hostImpl.OnComponentChanged(_component, md, oldName, _name);
                    }
                }
            }
        }

        public object GetService(Type service)
        {
            if (service == typeof (IDictionaryService))
            {
                return this;
            }
            // forward request to the host
            return _host.GetService(service);
        }

        #endregion

        #region IDictionaryService Implementation

        public object GetKey(object value)
        {
            return _dictionaryService.GetKey(value);
        }

        public object GetValue(object key)
        {
            return _dictionaryService.GetValue(key);
        }

        public void SetValue(object key, object value)
        {
            _dictionaryService.SetValue(key, value);
        }

        #endregion
    }
}